W tej pracy domowej dla 3-wymiarowego zbioru danych przetestuję 2 metody klasteryzacji:
oraz w celu wyznaczenia optymalnej liczby klastrów skorzystam z 3 metryk:
Ponadto, użyję metody wizualnej oraz wykorzystam pakiet NbClust.
data <- read.csv("../../clustering_R3.csv")
dataS <- as.data.frame(scale(data, scale = TRUE, center = TRUE))
plot_ly(x = dataS$X1, y = dataS$X2, z = dataS$X3, type = "scatter3d", mode = "markers")
km <- list(numeric(0)) # initializing variable containing results
hc <- list(numeric(0)) # initializing variable containing results
for (i in 1:10){
km[[i]] <- kmeans(dataS, centers = i)$cluster
}
d <- dist(dataS)
for (i in 1:10){
hc[[i]] <- cutree(hclust(d, method = "average"), i)
}
Współczynnik Solhouette jest miarą tego jak podobna jest dana obserwacja do swojego własnego klastra (cohesion) w porównaniu do innych występujących klastrów (separation). Silhouette przyjmuje wartości od -1 do +1, gdzie im wyższa wartość tym lepiej dana obserwacja jest przypisana do swojego klastra i tym mniejsza jest jej relacja z innymi klastrami.
Im większy (bliższy 1) tym lepszy.
Ten indeks jest określony jako stosunek między miarą rozproszenia wewnątrz klastra do miary rozproszenia międzyklastrowego.
Im większy tym lepszy.
Jest to stosunek minimalnej odległości między 2 obserwacjami w różnych klastrach do maksymalnej odległości między 2 różnymi obserwacjami należącymi do danego klastra.
Dunn’s index = minimum intercluster distance / maximum cluster diameter
Im większy tym lepszy.
silhouette.km <- list(numeric(0))
silhouette.hc <- list(numeric(0))
ch.km <- list(numeric(0))
ch.hc <- list(numeric(0))
dunn.km <- list(numeric(0))
dunn.hc <- list(numeric(0))
for (i in 2:10){
staty.km <- cluster.stats(d, km[[i]]) # fpc library
staty.hc <- cluster.stats(d, hc[[i]]) # fpc library
silhouette.km[[i]] <- staty.km$avg.silwidth
silhouette.hc[[i]] <- staty.hc$avg.silwidth
ch.km[[i]] <- staty.km$ch
ch.hc[[i]] <- staty.hc$ch
dunn.km[[i]] <- staty.km$dunn
dunn.hc[[i]] <- staty.hc$dunn
}
plot(x = 1:10, y = silhouette.km, main = "SILHOUETTE - kmeans",
ylab = "Silhouette index", xlab = "Number of clusters") # 2
2 - najlepsza liczba klastrów wg powyższej metryki
plot(x = 1:10, y = silhouette.hc, main = "SILHOUETTE - hclust",
ylab = "Silhouette index", xlab = "Number of clusters") # 2
2 - najlepsza liczba klastrów wg powyższej metryki
plot(x = 1:10, y = ch.km, main = "CALINSKI HARABASZ - kmeans",
ylab = "Calinski Harabasz index", xlab = "Number of clusters") # 7
7 - najlepsza liczba klastrów wg powyższej metryki
plot(x = 1:10, y = ch.hc, main = "CALINSKI HARABASZ - hclust",
ylab = "Calinski Harabasz index", xlab = "Number of clusters") # 7
7 - najlepsza liczba klastrów wg powyższej metryki
plot(x = 1:10, y = silhouette.km, main = "DUNN - kmeans",
ylab = "Dunn's index", xlab = "Number of clusters") # 2
2 - najlepsza liczba klastrów wg powyższej metryki
plot(x = 1:10, y = silhouette.hc, main = "DUNN - hclust",
ylab = "Dunn's index", xlab = "Number of clusters") # 2
2 - najlepsza liczba klastrów wg powyższej metryki
Najczęściej najlepsza występująca liczba klastrów to 2. Dodam również wizualizację dla 7 klastrów w celu porównania.
# kmeans - 2 centers
plot_ly(x = dataS$X1, y = dataS$X2, z = dataS$X3, type = "scatter3d", mode = "markers", color = km[[2]])
# kmeans - 7 centers
plot_ly(x = dataS$X1, y = dataS$X2, z = dataS$X3, type = "scatter3d", mode = "markers", color = km[[7]])
# clust 2
plot_ly(x = dataS$X1, y = dataS$X2, z = dataS$X3, type = "scatter3d", mode = "markers", color = hc[[2]])
# clust 7
plot_ly(x = dataS$X1, y = dataS$X2, z = dataS$X3, type = "scatter3d", mode = "markers", color = hc[[7]])
nc <- NbClust(data = dataS, method = "complete")
## *** : The Hubert index is a graphical method of determining the number of clusters.
## In the plot of Hubert index, we seek a significant knee that corresponds to a
## significant increase of the value of the measure i.e the significant peak in Hubert
## index second differences plot.
##
## *** : The D index is a graphical method of determining the number of clusters.
## In the plot of D index, we seek a significant knee (the significant peak in Dindex
## second differences plot) that corresponds to a significant increase of the value of
## the measure.
##
## *******************************************************************
## * Among all indices:
## * 6 proposed 2 as the best number of clusters
## * 1 proposed 3 as the best number of clusters
## * 7 proposed 4 as the best number of clusters
## * 1 proposed 8 as the best number of clusters
## * 5 proposed 9 as the best number of clusters
## * 2 proposed 10 as the best number of clusters
## * 2 proposed 15 as the best number of clusters
##
## ***** Conclusion *****
##
## * According to the majority rule, the best number of clusters is 4
##
##
## *******************************************************************
nc$Best.nc # 4
## KL CH Hartigan CCC Scott Marriot
## Number_clusters 4.0000 9.00 3.000 9.0000 4.000 4
## Value_Index 45.0489 2745.67 1736.772 55.6771 2623.278 295636937
## TrCovW TraceW Friedman Rubin Cindex DB
## Number_clusters 4.0 4.0000 9.0000 9.0000 9.0000 10.0000
## Value_Index 527340.5 877.7151 45.9451 -6.7888 0.2014 0.6732
## Silhouette Duda PseudoT2 Beale Ratkowsky Ball
## Number_clusters 10.000 2.0000 2.0000 2.0000 2.0000 4.0000
## Value_Index 0.601 0.6913 134.3895 0.7576 0.4835 355.3094
## PtBiserial Frey McClain Dunn Hubert SDindex Dindex
## Number_clusters 4.0000 2.0000 2.0000 15.000 0 8.0000 0
## Value_Index 0.7869 2.5957 0.3707 0.057 0 2.6923 0
## SDbw
## Number_clusters 15.0000
## Value_Index 0.0909
Według NbClust oraz posługując się metodą wizualną można dojść do wniosku, że 4 najlepszą liczbą klastrów dla tego zbioru danych.
Niestety wybrane metody klasteryzacji źle klasteryzują dla tej liczby klastrów:
# kmeans - 4 centers
plot_ly(x = dataS$X1, y = dataS$X2, z = dataS$X3, type = "scatter3d", mode = "markers", color = km[[4]])
# clust 4 clusters
plot_ly(x = dataS$X1, y = dataS$X2, z = dataS$X3, type = "scatter3d", mode = "markers", color = hc[[4]])
Porzebna nam jest inna metoda, pomysłem był hclust z metodą ‘single’:
# THE BEST: hclust (single) with 4 clusters
plot_ly(x = dataS$X1, y = dataS$X2, z = dataS$X3, type = "scatter3d", mode = "markers", color = cutree(hclust(d, method = 'single'),4))
Metoda klasteryzacji hclust ‘single’ oraz liczba klastrów 4 wydają się być idealne.
Porównując metody klasteryzajci kmeans oraz hclust z metodą ‘average’ doszedłem do wniosku, że najlepsza dla nich liczba klastrów to 2 albo 7. Jednakże, lepsza od nich jest metoda klasteryzacji hierarchicznej hclust z wykorzystaniem metody ‘single’ dla 4 klastrów - taki wniosek wysnułem po zastosowaniu NbClust oraz obejrzeniu wizualnym zbioru danych w 3D.
Oświadczam, że niniejsza praca stanowiąca podstawę do uznania osiągnięcia efektów uczenia się z przedmiotu Wstęp do uczenia maszynowego została wykonana przeze mnie samodzielnie.